#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/select.h>
using namespace std;
static const string ip = "127.0.0.1";
static const uint16_t port = 8080;
int main(int argc, char *argv[])
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(ip.c_str());
    server.sin_port = htons(port);
    connect(socket_fd, (struct sockaddr *)&server, sizeof(server));
    // v1 客户端v1 服务端v1
    //  int file_name_len = 0;
    //  recv(socket_fd, &file_name_len, sizeof(int), 0);
    //  char filename[1024] = {0};
    //  recv(socket_fd, filename, file_name_len, 0);
    //  off_t file_size = 0;
    //  recv(socket_fd, &file_size, sizeof(off_t), MSG_WAITALL);
    //  cout << "file_size : " << file_size << endl;
    //  int file_fd = open(filename, O_RDWR | O_CREAT, 0666);
    //  while (true)
    //  {
    //      int buf_len = 0;
    //      int ret = recv(socket_fd, &buf_len, sizeof(int), MSG_WAITALL);
    //      if (ret == 0)
    //      {
    //          break;
    //      }
    //      if (buf_len != 1000)
    //      {
    //          cout << "buf_len : " << buf_len << endl;
    //      }
    //      char buf[1000] = {0};
    //      ret = recv(socket_fd, buf, buf_len, MSG_WAITALL);
    //      if (ret == 0)
    //      {
    //          break;
    //      }
    //      write(file_fd, buf, buf_len);
    //      // if (buf_len == 996)
    //      // {
    //      //     cout << buf[997] << endl;
    //      // }
    //  }
    // v2 客户端v2 服务端v2
    int file_name_len = 0;
    recv(socket_fd, &file_name_len, sizeof(int), 0);
    char filename[1024] = {0};
    recv(socket_fd, filename, file_name_len, 0);
    off_t file_size = 0;
    recv(socket_fd, &file_size, sizeof(off_t), MSG_WAITALL);
    int file_fd = open(filename, O_RDWR | O_CREAT, 0666);
    ftruncate(file_fd, file_size);
    void *p = mmap(nullptr, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, file_fd, 0);
    recv(socket_fd, p, file_size, MSG_WAITALL);
    munmap(p, file_size);
    close(file_fd);
    close(socket_fd);
    return 0;
}